#!/bin/bash
# Linux系统初始化脚本
# 版本：2.0
# 支持：CentOS/RHEL/Ubuntu/Debian
# 作者：didiplus

# 颜色定义
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
NC='\033[0m'

# 系统检测
OS_ID=$(grep -E '^ID=' /etc/os-release | cut -d= -f2 | tr -d '"')
OS_VER=$(grep -E '^VERSION_ID=' /etc/os-release | cut -d= -f2 | tr -d '"')

# 通用函数
backup_file() {
    [ -f "$1" ] && cp "$1" "${1}.bak_$(date +%Y%m%d%H%M%S)"
}

#------------------------ 内核优化函数 ------------------------#
optimize_kernel_parameters() {
    sysctl_config="/etc/sysctl.conf"
    backup_file "$sysctl_config"

    echo -e "${YELLOW}正在优化内核参数...${NC}"

    # 增加文件描述符限制
    echo -e "${GREEN}增加文件描述符限制...${NC}"
    if grep -q "^#*fs.file-max" "$sysctl_config"; then
        sed -i "s/^#*fs.file-max.*/fs.file-max = 100000/" "$sysctl_config"
    else
        echo "fs.file-max = 100000" >> "$sysctl_config"
    fi

    # 调整网络参数
    echo -e "${GREEN}调整网络参数...${NC}"
    if grep -q "^#*net.core.somaxconn" "$sysctl_config"; then
        sed -i "s/^#*net.core.somaxconn.*/net.core.somaxconn = 65535/" "$sysctl_config"
    else
        echo "net.core.somaxconn = 65535" >> "$sysctl_config"
    fi

    if grep -q "^#*net.ipv4.tcp_max_syn_backlog" "$sysctl_config"; then
        sed -i "s/^#*net.ipv4.tcp_max_syn_backlog.*/net.ipv4.tcp_max_syn_backlog = 65535/" "$sysctl_config"
    else
        echo "net.ipv4.tcp_max_syn_backlog = 65535" >> "$sysctl_config"
    fi

    if grep -q "^#*net.ipv4.tcp_tw_reuse" "$sysctl_config"; then
        sed -i "s/^#*net.ipv4.tcp_tw_reuse.*/net.ipv4.tcp_tw_reuse = 1/" "$sysctl_config"
    else
        echo "net.ipv4.tcp_tw_reuse = 1" >> "$sysctl_config"
    fi

    if grep -q "^#*net.ipv4.tcp_fin_timeout" "$sysctl_config"; then
        sed -i "s/^#*net.ipv4.tcp_fin_timeout.*/net.ipv4.tcp_fin_timeout = 30/" "$sysctl_config"
    else
        echo "net.ipv4.tcp_fin_timeout = 30" >> "$sysctl_config"
    fi

    if grep -q "^#*net.ipv4.ip_local_port_range" "$sysctl_config"; then
        sed -i "s/^#*net.ipv4.ip_local_port_range.*/net.ipv4.ip_local_port_range = 1024 65535/" "$sysctl_config"
    else
        echo "net.ipv4.ip_local_port_range = 1024 65535" >> "$sysctl_config"
    fi

    # 调整虚拟内存参数
    echo -e "${GREEN}调整虚拟内存参数...${NC}"
    if grep -q "^#*vm.swappiness" "$sysctl_config"; then
        sed -i "s/^#*vm.swappiness.*/vm.swappiness = 10/" "$sysctl_config"
    else
        echo "vm.swappiness = 10" >> "$sysctl_config"
    fi

    if grep -q "^#*vm.vfs_cache_pressure" "$sysctl_config"; then
        sed -i "s/^#*vm.vfs_cache_pressure.*/vm.vfs_cache_pressure = 50/" "$sysctl_config"
    else
        echo "vm.vfs_cache_pressure = 50" >> "$sysctl_config"
    fi

    # 调整进程限制
    echo -e "${GREEN}调整进程限制...${NC}"
    if grep -q "^#*kernel.pid_max" "$sysctl_config"; then
        sed -i "s/^#*kernel.pid_max.*/kernel.pid_max = 65536/" "$sysctl_config"
    else
        echo "kernel.pid_max = 65536" >> "$sysctl_config"
    fi

    # 应用新的内核参数
    sysctl -p

    echo -e "${GREEN}内核参数优化已完成${NC}"
}

#------------------------ 设置PS1样式------------------------#
set_ps1_style() {
    echo -e "${YELLOW}当前PS1样式: $PS1${NC}"
    echo -e "您可以使用以下变量来自定义PS1样式："
    echo -e "\t\\u - 用户名"
    echo -e "\t\\h - 主机名（短主机名）"
    echo -e "\t\\H - 主机名（完整主机名）"
    echo -e "\t\\w - 当前工作目录的完整路径"
    echo -e "\t\\W - 当前工作目录的名称"
    echo -e "\t\\$ - 提示符（# 对于root用户，$ 对于普通用户）"
    echo -e "\t\\n - 换行"
    echo -e "\t\\t - 制表符"
    echo -e "\t\\e - ANSI转义码（用于颜色）"
    echo -e "\t\\[ 和 \\] - 用于非打印字符（如颜色代码），确保Bash正确计算提示符长度"

    read -p "请输入新的PS1样式: " new_ps1

    # 备份当前的PS1样式
    backup_file ~/.bashrc

    # 将新的PS1样式写入~/.bashrc
    if grep -q "^PS1=" ~/.bashrc; then
        sed -i "s/^PS1=.*/PS1=\"$new_ps1\"/" ~/.bashrc
    else
        echo "PS1=\"$new_ps1\"" >> ~/.bashrc
    fi

    # 应用新的PS1样式
    export PS1="$new_ps1"

    echo -e "${GREEN}PS1样式已设置为: ${BLUE}$new_ps1${NC}"
    echo -e "${GREEN}请重新打开终端或运行 'source ~/.bashrc' 以应用更改${NC}"
}

#------------------------ 修改SSH端口函数 ------------------------#
change_ssh_port() {
    read -p "请输入新的SSH端口号: " new_port
    if [[ ! $new_port =~ ^[0-9]+$ ]] || [ $new_port -lt 1 ] || [ $new_port -gt 65535 ]; then
        echo -e "${RED}无效的端口号，请输入1到65535之间的数字${NC}"
        return 1
    fi

    ssh_config="/etc/ssh/sshd_config"
    backup_file "$ssh_config"

    # 检查是否已经存在Port配置，如果存在则修改，否则添加
    if grep -q "^#*Port" "$ssh_config"; then
        sed -i "s/^#*Port.*/Port $new_port/" "$ssh_config"
    else
        echo "Port $new_port" >> "$ssh_config"
    fi

    # 重启SSH服务
    systemctl restart sshd
    echo -e "${GREEN}SSH端口已修改为 ${BLUE}$new_port${GREEN}，请确保防火墙已允许该端口的流量${NC}"
}
#------------------------ SSH安全优化 ------------------------#
ssh_security_optimize() {
    ssh_config="/etc/ssh/sshd_config"
    backup_file "$ssh_config"

    # 禁用root登录
    if grep -q "^#*PermitRootLogin" "$ssh_config"; then
        sed -i "s/^#*PermitRootLogin.*/PermitRootLogin no/" "$ssh_config"
    else
        echo "PermitRootLogin no" >> "$ssh_config"
    fi


    # 禁用旧版本的SSH协议（SSHv1）
    if grep -q "^#*Protocol" "$ssh_config"; then
        sed -i "s/^#*Protocol.*/Protocol 2/" "$ssh_config"
    else
        echo "Protocol 2" >> "$ssh_config"
    fi

    # 禁用DNS反向解析
    if grep -q "^#*UseDNS" "$ssh_config"; then
        sed -i "s/^#*UseDNS.*/UseDNS no/" "$ssh_config"
    else
        echo "UseDNS no" >> "$ssh_config"
    fi

    # 设置超时断开恢复间隔时长（秒）
    read -p "输入超时断开恢复间隔时长（秒）: " client_alive_interval
    if [[ ! $client_alive_interval =~ ^[0-9]+$ ]]; then
        echo -e "${RED}无效的输入，请输入一个数字${NC}"
        return 1
    fi
    if grep -q "^#*ClientAliveInterval" "$ssh_config"; then
        sed -i "s/^#*ClientAliveInterval.*/ClientAliveInterval $client_alive_interval/" "$ssh_config"
    else
        echo "ClientAliveInterval $client_alive_interval" >> "$ssh_config"
    fi

    # 设置超时断开尝试次数（次）
    read -p "输入超时断开尝试次数（次）: " client_alive_count_max
    if [[ ! $client_alive_count_max =~ ^[0-9]+$ ]]; then
        echo -e "${RED}无效的输入，请输入一个数字${NC}"
        return 1
    fi
    if grep -q "^#*ClientAliveCountMax" "$ssh_config"; then
        sed -i "s/^#*ClientAliveCountMax.*/ClientAliveCountMax $client_alive_count_max/" "$ssh_config"
    else
        echo "ClientAliveCountMax $client_alive_count_max" >> "$ssh_config"
    fi

    # 启用严格的权限检查
    chmod 600 "$ssh_config"
    chown root:root "$ssh_config"

    # 重启SSH服务
    systemctl restart sshd
    echo -e "${GREEN}SSH安全优化已完成，请确保防火墙已允许新的配置${NC}"
}

#------------------------ 配置国内源 ------------------------#
configure_china_mirrors() {
    case $OS_ID in
        "centos"|"rhel")
            echo -e "${YELLOW}正在配置CentOS/RHEL国内源（阿里云）...${NC}"
            repo_file="/etc/yum.repos.d/CentOS-Base.repo"
            backup_file "$repo_file"

            # 下载阿里云的CentOS/RHEL镜像源
            wget -O "$repo_file" http://mirrors.aliyun.com/repo/Centos-7.repo
            if [ $? -ne 0 ]; then
                echo -e "${RED}下载阿里云镜像源失败，请手动配置${NC}"
                return 1
            fi

            # 清理并更新YUM缓存
            yum clean all
            yum makecache
            echo -e "${GREEN}CentOS/RHEL国内源配置完成${NC}"
            ;;

        "ubuntu"|"debian")
            echo -e "${YELLOW}正在配置Ubuntu/Debian国内源（阿里云）...${NC}"
            sources_list="/etc/apt/sources.list"
            backup_file "$sources_list"

            # 根据不同的Ubuntu/Debian版本配置不同的源
            case $OS_ID in
                "ubuntu")
                    case $OS_VER in
                        "18.04")
                            cat > "$sources_list" << EOF
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
EOF
                            ;;
                        "20.04")
                            cat > "$sources_list" << EOF
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
EOF
                            ;;
                        "22.04")
                            cat > "$sources_list" << EOF
deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
EOF
                            ;;
                        *)
                            echo -e "${RED}不支持的Ubuntu版本，请手动配置${NC}"
                            return 1
                            ;;
                    esac
                    ;;
                "debian")
                    case $OS_VER in
                        "9")
                            cat > "$sources_list" << EOF
deb http://mirrors.aliyun.com/debian/ stretch main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ stretch main non-free contrib

deb http://mirrors.aliyun.com/debian-security stretch/updates main
deb-src http://mirrors.aliyun.com/debian-security stretch/updates main

deb http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib

deb http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib
EOF
                            ;;
                        "10")
                            cat > "$sources_list" << EOF
deb http://mirrors.aliyun.com/debian/ buster main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster main non-free contrib

deb http://mirrors.aliyun.com/debian-security buster/updates main
deb-src http://mirrors.aliyun.com/debian-security buster/updates main

deb http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib

deb http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib
EOF
                            ;;
                        "11")
                            cat > "$sources_list" << EOF
deb http://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye main non-free contrib

deb http://mirrors.aliyun.com/debian-security bullseye-security main
deb-src http://mirrors.aliyun.com/debian-security bullseye-security main

deb http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib

deb http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
EOF
                            ;;
                        *)
                            echo -e "${RED}不支持的Debian版本，请手动配置${NC}"
                            return 1
                            ;;
                    esac
                    ;;
                *)
                    echo -e "${RED}不支持的操作系统，请手动配置${NC}"
                    return 1
                    ;;
            esac

            # 更新APT缓存
            apt-get update
            echo -e "${GREEN}Ubuntu/Debian国内源配置完成${NC}"
            ;;
        *)
            echo -e "${RED}不支持的操作系统，请手动配置${NC}"
            return 1
            ;;
    esac
}
#------------------------ History格式优化 ------------------------#
optimize_history_format() {
    history_config="$HOME/.bashrc"
    backup_file "$history_config"

    echo -e "${YELLOW}正在优化History格式...${NC}"

    # 增加历史记录条数
    echo -e "${GREEN}增加历史记录条数...${NC}"
    if grep -q "^#*HISTSIZE" "$history_config"; then
        sed -i "s/^#*HISTSIZE.*/HISTSIZE=10000/" "$history_config"
    else
        echo "HISTSIZE=10000" >> "$history_config"
    fi

    if grep -q "^#*HISTFILESIZE" "$history_config"; then
        sed -i "s/^#*HISTFILESIZE.*/HISTFILESIZE=20000/" "$history_config"
    else
        echo "HISTFILESIZE=20000" >> "$history_config"
    fi

    # 忽略重复命令
    echo -e "${GREEN}忽略重复命令...${NC}"
    if grep -q "^#*HISTCONTROL" "$history_config"; then
        sed -i "s/^#*HISTCONTROL.*/HISTCONTROL=ignoredups:erasedups/" "$history_config"
    else
        echo "HISTCONTROL=ignoredups:erasedups" >> "$history_config"
    fi

    # 忽略特定命令
    echo -e "${GREEN}忽略特定命令...${NC}"
    if grep -q "^#*HISTIGNORE" "$history_config"; then
        sed -i "s/^#*HISTIGNORE.*/HISTIGNORE=exit:history/" "$history_config"
    else
        echo "HISTIGNORE=exit:history" >> "$history_config"
    fi

    # 记录命令执行时间
    echo -e "${GREEN}记录命令执行时间...${NC}"
    if grep -q "^#*HISTTIMEFORMAT" "$history_config"; then
        sed -i "s/^#*HISTTIMEFORMAT.*/HISTTIMEFORMAT='%F %T '" "$history_config"
    else
        echo "HISTTIMEFORMAT='%F %T '" >> "$history_config"
    fi

    # 使更改立即生效
    source "$history_config"

    echo -e "${GREEN}History格式优化已完成${NC}"
}

#------------------------ 核心功能实现 ------------------------#
setup_network() {
    interface_num=$1
    echo -e "${YELLOW}[$((interface_num+1))] 配置${interface_num}网卡网络...${NC}"
    
    for ((i=1; i<=interface_num; i++)); do
        read -p "输入网卡${i}名称(如eth0): " dev
        read -p "输入IP地址/CIDR(如192.168.1.10/24): " ip
        read -p "输入网关: " gw
        read -p "输入DNS(空格分隔): " dns

        case $OS_ID in
        "centos"|"rhel")
            cfg="/etc/sysconfig/network-scripts/ifcfg-${dev}"
            cat > "$cfg" << EOF
DEVICE=${dev}
BOOTPROTO=none
ONBOOT=yes
IPADDR=${ip%%/*}
PREFIX=${ip##*/}
GATEWAY=${gw}
DNS1=${dns%% *}
EOF
            ;;
        "ubuntu"|"debian")
            # 动态查找Netplan配置文件
            cfg=$(ls /etc/netplan/*.yaml 2>/dev/null | head -n 1)
            if [ -z "$cfg" ]; then
                echo -e "${RED}未找到Netplan配置文件，请手动配置网络${NC}"
                return 1
            fi
            backup_file "$cfg"
            [ $i -eq 1 ] && echo -e "network:\n  version: 2\n  renderer: networkd\n  ethernets:" > "$cfg"
            cat >> "$cfg" << EOF
    ${dev}:
      addresses: [${ip}]
      routes:
        - to: default
          via: ${gw}
      nameservers:
        addresses: [${dns}]
EOF
            ;;
        esac
    done
    
    [ "$OS_ID" = "ubuntu" ] && netplan apply || systemctl restart network
}

set_hostname() {
    read -p "输入新主机名: " new_hostname
    hostnamectl set-hostname "$new_hostname"
    sed -i "/127.0.1.1/d" /etc/hosts
    echo -e "127.0.1.1\t$new_hostname" >> /etc/hosts
    echo -e "${GREEN}主机名已设置为 ${BLUE}${new_hostname}${NC}"
}

disable_swap() {
    swapoff -a
    sed -i '/swap/d' /etc/fstab
    echo -e "${GREEN}SWAP已永久禁用${NC}"
}

#------------------------ 其他功能函数 ------------------------#
set_timezone() { timedatectl set-timezone Asia/Shanghai; }


#------------------------ 主菜单 ------------------------#
while :; do
    clear
    echo -e "${BLUE}================ 系统初始化菜单 ================${NC}"
    echo -e "1. 修改网卡名\t\t15. History格式优化"
    echo -e "2. 单网卡配置\t\t16. 重启系统"
    echo -e "3. 双网卡配置\t\t"
    echo -e "4. 设置主机名\t\t"
    echo -e "5. 配置国内源\t\t"
    echo -e "6. 关闭防火墙\t"
    echo -e "7. 禁用SELinux\t\t"
    echo -e "8. 禁用SWAP\t\t"
    echo -e "9. 设置时区\t\t"
    echo -e "10. 内核参数优化\t\t"
    echo -e "11. SSH安全优化\t\t"
    echo -e "12. 修改SSH端口\t"
    echo -e "13. 设置系统别名\t27. 关机"
    echo -e "14. 置PS1样式\t\tq. 退出"
    echo -e "${BLUE}===============================================${NC}"
    
    read -p "请输入选项数字: " choice
    case $choice in
        1) change_nic_name ;;
        2) setup_network 1 ;;
        3) setup_network 2 ;;
        4) set_hostname ;;
        5) configure_china_mirrors;;
        6) systemctl stop firewalld; systemctl disable firewalld ;;
        7) setenforce 0; sed -i 's/SELINUX=.*/SELINUX=disabled/' /etc/selinux/config ;;
        8) disable_swap ;;
        9) set_timezone ;;
        10) optimize_kernel_parameters ;;
        11) ssh_security_optimize;;
        12) change_ssh_port;;
        15) optimize_history_format;;
        16) reboot ;;
        27) shutdown -h now ;;
        q) exit 0 ;;
        *) echo -e "${RED}无效选项，请重新输入${NC}" ;;
    esac
    read -p "按回车返回主菜单..."
done